/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package sample;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class Saml2LoginApplicationITests {
	static final String SIGNED_RESPONSE = "PHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIElEPSJfOGU1NjU1ZWQ3Y2E1NWUyODZiNjE1MDA4OGVjNzU1ZjY2MGY1NzQxY2M3IiBWZXJzaW9uPSIyLjAiIElzc3VlSW5zdGFudD0iMjAyMC0wOC0yOFQyMToxMDoyNVoiIERlc3RpbmF0aW9uPSJodHRwOi8vbG9jYWxob3N0OjgwODAvbG9naW4vc2FtbDIvc3NvL29uZSIgSW5SZXNwb25zZVRvPSJBUlFiOGYzMzQzLWQzMzMtNDFhMy1hMTk0LTE2MTdhYTY0YjNiMyI+PHNhbWw6SXNzdWVyPmh0dHBzOi8vc2ltcGxlc2FtbC1mb3Itc3ByaW5nLXNhbWwuY2ZhcHBzLmlvL3NhbWwyL2lkcC9tZXRhZGF0YS5waHA8L3NhbWw6SXNzdWVyPjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPgogIDxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIi8+CiAgICA8ZHM6U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPgogIDxkczpSZWZlcmVuY2UgVVJJPSIjXzhlNTY1NWVkN2NhNTVlMjg2YjYxNTAwODhlYzc1NWY2NjBmNTc0MWNjNyI+PGRzOlRyYW5zZm9ybXM+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPjwvZHM6VHJhbnNmb3Jtcz48ZHM6RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjc2hhMjU2Ii8+PGRzOkRpZ2VzdFZhbHVlPjNOQkxaaHBjMEpxOVAwSDhVQzFPRmFUN2hPY0QxNGZneWNlRFZ3dEw5VDA9PC9kczpEaWdlc3RWYWx1ZT48L2RzOlJlZmVyZW5jZT48L2RzOlNpZ25lZEluZm8+PGRzOlNpZ25hdHVyZVZhbHVlPmN1YVhvYVl2Y2ZBOWg5bENRbFNsVVZjMzV6K294SGRWZkFVMk5sQ2U4cFhLa25RVkF6ZkNQSVJRZDdyWTdyQlc4OVpTb0Jsd2RsS1Iwemx4cHBySnVNenZyZE1lOWhybU1pU2hWcWlXQzVKRmhDSndKWGxpdzBEWGk5VEZ6NkcxSDBRYm1nVHRkZDJOYUIzR25WRFhsRi93ZWx0aUFDUTNDNUp2aE1HN1B5UmdQWGJFa0lkWWxzZ2FmTS9RYW9yUDdNQjJXNU1sWnhCYmFla043Qm9EdTVNZkhhMU9RK3ZDQ0h5R0hQbG1JTjdmbW80N29xWFNhMTVyUTBvVFBld1lMakVFMldrL2x6WiszdThOSHArbVY5Ukc2dXlWRHEyU1JsVm5XUElQL0pXaVdFVjhVRU13K0Q2R1NyNnQxN1E2QWV2VHNCRmRxZ1A3UTIySWRyZzBrUT09PC9kczpTaWduYXR1cmVWYWx1ZT4KPGRzOktleUluZm8+PGRzOlg1MDlEYXRhPjxkczpYNTA5Q2VydGlmaWNhdGU+TUlJRUV6Q0NBdnVnQXdJQkFnSUpBSWMxcXpMcnYrNW5NQTBHQ1NxR1NJYjNEUUVCQ3dVQU1JR2ZNUXN3Q1FZRFZRUUdFd0pWVXpFTE1Ba0dBMVVFQ0F3Q1EwOHhGREFTQmdOVkJBY01DME5oYzNSc1pTQlNiMk5yTVJ3d0dnWURWUVFLREJOVFlXMXNJRlJsYzNScGJtY2dVMlZ5ZG1WeU1Rc3dDUVlEVlFRTERBSkpWREVnTUI0R0ExVUVBd3dYYzJsdGNHeGxjMkZ0YkhCb2NDNWpabUZ3Y0hNdWFXOHhJREFlQmdrcWhraUc5dzBCQ1FFV0VXWm9ZVzVwYTBCd2FYWnZkR0ZzTG1sdk1CNFhEVEUxTURJeU16SXlORFV3TTFvWERUSTFNREl5TWpJeU5EVXdNMW93Z1o4eEN6QUpCZ05WQkFZVEFsVlRNUXN3Q1FZRFZRUUlEQUpEVHpFVU1CSUdBMVVFQnd3TFEyRnpkR3hsSUZKdlkyc3hIREFhQmdOVkJBb01FMU5oYld3Z1ZHVnpkR2x1WnlCVFpYSjJaWEl4Q3pBSkJnTlZCQXNNQWtsVU1TQXdIZ1lEVlFRRERCZHphVzF3YkdWellXMXNjR2h3TG1ObVlYQndjeTVwYnpFZ01CNEdDU3FHU0liM0RRRUpBUllSWm1oaGJtbHJRSEJwZG05MFlXd3VhVzh3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQzRjbjYyRTF4THFwTjM0UG1icktCYmtPWEZqeldnSjliK3BYdWFSZnQ2QTMzOXV1SVFlb2VINXFlU0tSVlRsMzJMMGdkejJaaXZMd1pYVytjcXZmdFZXMXR2RUh2ekpGeXhlVFczZkNVZUNRc2ViTG5BMnFSYTA3Umt4VG82TmYyNDRtV1dSRG9kY29IRWZEVVNieGZUWjZJRXhTb2pTSVUyUm5ENldsbFlXRmREMUdGcEJKT21RQjhyQWM4d0pJQmRIRmRRblg4VHRsN2haNnJ0Z3FFWU16WVZNdUoyRjJyMUhTVTF6U0F2d3BkWVA2clJHRlJKRWZkQTltbTNXS2ZOTFNjNWNsanowWC9UWHkwdlZsQVY5NWw5cWNmRnpQbXJrTklzdDlGWlN3cHZCNDlMeUFWa2UwNEZRUFB3TGdWSDRncGhpSkgzanZaN0krSjVsUzhWQWdNQkFBR2pVREJPTUIwR0ExVWREZ1FXQkJUVHlQNkNjNUhsQko1K3VjVkN3R2M1b2dLTkd6QWZCZ05WSFNNRUdEQVdnQlRUeVA2Q2M1SGxCSjUrdWNWQ3dHYzVvZ0tOR3pBTUJnTlZIUk1FQlRBREFRSC9NQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUF2TVM0RVFlUC9pcFY0ak9HNWxPNi90WUNiL2lKZUFkdU9uUmhrSmswRGJYMzI5bERMWmhUVEwveC93LzltdUNWY3ZMcnpFcDZQTitWV2Z3NUU1Rld0Wk4weWhHdFA5Uit2Wm5yVitvYzJ6R0Qrbm8xL3lTRk9lM0VpSkNPNWRlaHhLallFbUJSdjVzVS9MWkZLWnBvektOL0JNRWE2Q3FMdXhiemI3eWt4VnI3RVZGWHdsdFB4ekU5VG1MOU9BQ05OeUY1ZUpIV01STWxsYXJVdmtjWGxoNHB1eDRrczllNnpWOURRQnkyemRzOWYxSTNxeGcwZVg2Sm5HclhpL1ppQ1QrbEpnVmUzWkZYaWVqaUxBaUtCMDRzWFczdGkwTFczbHgxM1kxWWxRNC90bHBnVGdmSUp4S1Y2bnlQaUxvSzBueXdiTWQrdnBBaXJEdDJPYytoazwvZHM6WDUwOUNlcnRpZmljYXRlPjwvZHM6WDUwOURhdGE+PC9kczpLZXlJbmZvPjwvZHM6U2lnbmF0dXJlPjxzYW1scDpTdGF0dXM+PHNhbWxwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIvPjwvc2FtbHA6U3RhdHVzPjxzYW1sOkFzc2VydGlvbiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIElEPSJfYmE3MjllMmNhYTRkZmExNmY3ZDQwM2MxNzUwNmE5MTM1Zjk3YzAwN2Y4IiBWZXJzaW9uPSIyLjAiIElzc3VlSW5zdGFudD0iMjAyMC0wOC0yOFQyMToxMDoyNVoiPjxzYW1sOklzc3Vlcj5odHRwczovL3NpbXBsZXNhbWwtZm9yLXNwcmluZy1zYW1sLmNmYXBwcy5pby9zYW1sMi9pZHAvbWV0YWRhdGEucGhwPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4KICA8ZHM6U2lnbmVkSW5mbz48ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPgogICAgPGRzOlNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZHNpZy1tb3JlI3JzYS1zaGEyNTYiLz4KICA8ZHM6UmVmZXJlbmNlIFVSST0iI19iYTcyOWUyY2FhNGRmYTE2ZjdkNDAzYzE3NTA2YTkxMzVmOTdjMDA3ZjgiPjxkczpUcmFuc2Zvcm1zPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjZW52ZWxvcGVkLXNpZ25hdHVyZSIvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48L2RzOlRyYW5zZm9ybXM+PGRzOkRpZ2VzdE1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMDQveG1sZW5jI3NoYTI1NiIvPjxkczpEaWdlc3RWYWx1ZT5EdHpJNnJ5SjE0VjdFelpGaU51UHl2RUZiWEYxbmZBTk5ZWTE3QWJaMTEwPTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT5LQ2ZmRytCSWJHeC92ZlV1VnEyU25qOHdYM0htKytPZFVnRmFkR0hhazhBL1hPQzJwVERoNkJZcWFjTzhDcUhBR29vekZrcFZhTU9pN053MmpFUnVMaGg3aG1GVzB2aE9tK2c4UUVxM3VCMGVkY3dsaUtya1RtZ0VjZE5lRW1pem15QUJpeHdEbHFHd1MzSnA4MHdrQ1NxSyt5TEFsMlJoWkg0Q0kvMTVrZVcxSURjSDg3Ly9pMXNlOVk5U1lVVTZjaGpsVjFPa0MxWXR5dGpwNXlUd1pxb1JqUXRKMFlVSnp6TFVOTHJaR0xvZG50azR0VzNJZ2FVM293OGk2dDZSZWpReG1nNHNJTGcxNzgvblU3dG8vRmdtRnc2UmM4TmhqYW5EY2FyZjdyb1crVVlmQnpBYmNLYU1NaEFVeUh4RjB0VU4xS2NHeDVxTXFNRVFOdS9iRFE9PTwvZHM6U2lnbmF0dXJlVmFsdWU+CjxkczpLZXlJbmZvPjxkczpYNTA5RGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUVFekNDQXZ1Z0F3SUJBZ0lKQUljMXF6THJ2KzVuTUEwR0NTcUdTSWIzRFFFQkN3VUFNSUdmTVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHQTFVRUNBd0NRMDh4RkRBU0JnTlZCQWNNQzBOaGMzUnNaU0JTYjJOck1Sd3dHZ1lEVlFRS0RCTlRZVzFzSUZSbGMzUnBibWNnVTJWeWRtVnlNUXN3Q1FZRFZRUUxEQUpKVkRFZ01CNEdBMVVFQXd3WGMybHRjR3hsYzJGdGJIQm9jQzVqWm1Gd2NITXVhVzh4SURBZUJna3Foa2lHOXcwQkNRRVdFV1pvWVc1cGEwQndhWFp2ZEdGc0xtbHZNQjRYRFRFMU1ESXlNekl5TkRVd00xb1hEVEkxTURJeU1qSXlORFV3TTFvd2daOHhDekFKQmdOVkJBWVRBbFZUTVFzd0NRWURWUVFJREFKRFR6RVVNQklHQTFVRUJ3d0xRMkZ6ZEd4bElGSnZZMnN4SERBYUJnTlZCQW9NRTFOaGJXd2dWR1Z6ZEdsdVp5QlRaWEoyWlhJeEN6QUpCZ05WQkFzTUFrbFVNU0F3SGdZRFZRUUREQmR6YVcxd2JHVnpZVzFzY0dod0xtTm1ZWEJ3Y3k1cGJ6RWdNQjRHQ1NxR1NJYjNEUUVKQVJZUlptaGhibWxyUUhCcGRtOTBZV3d1YVc4d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUUM0Y242MkUxeExxcE4zNFBtYnJLQmJrT1hGanpXZ0o5YitwWHVhUmZ0NkEzMzl1dUlRZW9lSDVxZVNLUlZUbDMyTDBnZHoyWml2THdaWFcrY3F2ZnRWVzF0dkVIdnpKRnl4ZVRXM2ZDVWVDUXNlYkxuQTJxUmEwN1JreFRvNk5mMjQ0bVdXUkRvZGNvSEVmRFVTYnhmVFo2SUV4U29qU0lVMlJuRDZXbGxZV0ZkRDFHRnBCSk9tUUI4ckFjOHdKSUJkSEZkUW5YOFR0bDdoWjZydGdxRVlNellWTXVKMkYycjFIU1UxelNBdndwZFlQNnJSR0ZSSkVmZEE5bW0zV0tmTkxTYzVjbGp6MFgvVFh5MHZWbEFWOTVsOXFjZkZ6UG1ya05Jc3Q5RlpTd3B2QjQ5THlBVmtlMDRGUVBQd0xnVkg0Z3BoaUpIM2p2WjdJK0o1bFM4VkFnTUJBQUdqVURCT01CMEdBMVVkRGdRV0JCVFR5UDZDYzVIbEJKNSt1Y1ZDd0djNW9nS05HekFmQmdOVkhTTUVHREFXZ0JUVHlQNkNjNUhsQko1K3VjVkN3R2M1b2dLTkd6QU1CZ05WSFJNRUJUQURBUUgvTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFBdk1TNEVRZVAvaXBWNGpPRzVsTzYvdFlDYi9pSmVBZHVPblJoa0prMERiWDMyOWxETFpoVFRML3gvdy85bXVDVmN2THJ6RXA2UE4rVldmdzVFNUZXdFpOMHloR3RQOVIrdlpuclYrb2MyekdEK25vMS95U0ZPZTNFaUpDTzVkZWh4S2pZRW1CUnY1c1UvTFpGS1pwb3pLTi9CTUVhNkNxTHV4YnpiN3lreFZyN0VWRlh3bHRQeHpFOVRtTDlPQUNOTnlGNWVKSFdNUk1sbGFyVXZrY1hsaDRwdXg0a3M5ZTZ6VjlEUUJ5MnpkczlmMUkzcXhnMGVYNkpuR3JYaS9aaUNUK2xKZ1ZlM1pGWGllamlMQWlLQjA0c1hXM3RpMExXM2x4MTNZMVlsUTQvdGxwZ1RnZklKeEtWNm55UGlMb0swbnl3Yk1kK3ZwQWlyRHQyT2MraGs8L2RzOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT48c2FtbDpTdWJqZWN0PjxzYW1sOk5hbWVJRCBTUE5hbWVRdWFsaWZpZXI9Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9zYW1sMi9zZXJ2aWNlLXByb3ZpZGVyLW1ldGFkYXRhL29uZSIgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDplbWFpbEFkZHJlc3MiPnRlc3R1c2VyQHNwcmluZy5zZWN1cml0eS5zYW1sPC9zYW1sOk5hbWVJRD48c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+PHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgTm90T25PckFmdGVyPSIyMDUyLTA1LTA2VDIyOjU3OjA1WiIgUmVjaXBpZW50PSJodHRwOi8vbG9jYWxob3N0OjgwODAvbG9naW4vc2FtbDIvc3NvL29uZSIgSW5SZXNwb25zZVRvPSJBUlFiOGYzMzQzLWQzMzMtNDFhMy1hMTk0LTE2MTdhYTY0YjNiMyIvPjwvc2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPjwvc2FtbDpTdWJqZWN0PjxzYW1sOkNvbmRpdGlvbnMgTm90QmVmb3JlPSIyMDIwLTA4LTI4VDIxOjA5OjU1WiIgTm90T25PckFmdGVyPSIyMDUyLTA1LTA2VDIyOjU3OjA1WiI+PHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj48c2FtbDpBdWRpZW5jZT5odHRwOi8vbG9jYWxob3N0OjgwODAvc2FtbDIvc2VydmljZS1wcm92aWRlci1tZXRhZGF0YS9vbmU8L3NhbWw6QXVkaWVuY2U+PC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24+PC9zYW1sOkNvbmRpdGlvbnM+PHNhbWw6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDIwLTA4LTI4VDIxOjEwOjI1WiIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAyMC0wOC0yOVQwNToxMDoyNVoiIFNlc3Npb25JbmRleD0iXzFhN2E4NjM4ZTg2Y2VhYTkyY2M1ODY0NmM0MjMxODc1YTZjOWQxY2FiYiI+PHNhbWw6QXV0aG5Db250ZXh0PjxzYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJvdGVjdGVkVHJhbnNwb3J0PC9zYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPjwvc2FtbDpBdXRobkNvbnRleHQ+PC9zYW1sOkF1dGhuU3RhdGVtZW50PjxzYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD48c2FtbDpBdHRyaWJ1dGUgTmFtZT0idWlkIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4c2k6dHlwZT0ieHM6c3RyaW5nIj50ZXN0dXNlckBzcHJpbmcuc2VjdXJpdHkuc2FtbDwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJlZHVQZXJzb25BZmZpbGlhdGlvbiIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDpiYXNpYyI+PHNhbWw6QXR0cmlidXRlVmFsdWUgeHNpOnR5cGU9InhzOnN0cmluZyI+bWVtYmVyPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPjxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhzaTp0eXBlPSJ4czpzdHJpbmciPnVzZXI8L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48c2FtbDpBdHRyaWJ1dGUgTmFtZT0iZW1haWxBZGRyZXNzIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OmJhc2ljIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4c2k6dHlwZT0ieHM6c3RyaW5nIj50ZXN0dXNlckBzcHJpbmcuc2VjdXJpdHkuc2FtbDwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjwvc2FtbDpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PC9zYW1sOkFzc2VydGlvbj48L3NhbWxwOlJlc3BvbnNlPg==";

	static final Map<String, List<Object>> USER_ATTRIBUTES = new LinkedHashMap<>();

	static {
		USER_ATTRIBUTES.put("uid", Arrays.asList("testuser@spring.security.saml"));
		USER_ATTRIBUTES.put("eduPersonAffiliation", Arrays.asList("member", "user"));
		USER_ATTRIBUTES.put("emailAddress", Arrays.asList("testuser@spring.security.saml"));
	}

	@Autowired
	MockMvc mvc;

	@Autowired
	WebClient webClient;

	@Test
	public void indexWhenSamlResponseThenShowsUserInformation() throws Exception {
		HttpSession session = this.mvc.perform(get("http://localhost:8080/"))
				.andExpect(status().is3xxRedirection())
				.andExpect(redirectedUrl("http://localhost:8080/saml2/authenticate/one"))
				.andReturn()
				.getRequest().getSession();

		this.mvc.perform(post("http://localhost:8080/login/saml2/sso/one")
				.param("SAMLResponse", SIGNED_RESPONSE)
				.session((MockHttpSession) session))
				.andExpect(redirectedUrl("http://localhost:8080/"));

		this.mvc.perform(get("http://localhost:8080/")
				.session((MockHttpSession) session))
				.andExpect(model().attribute("emailAddress", "testuser@spring.security.saml"))
				.andExpect(model().attribute("userAttributes", USER_ATTRIBUTES));
	}

	@Test
	public void authenticationAttemptWhenValidThenShowsUserEmailAddress() throws Exception {
		HtmlPage assertingParty = this.webClient.getPage("/");
		HtmlForm form = assertingParty.getFormByName("f");
		HtmlInput username = form.getInputByName("username");
		HtmlInput password = form.getInputByName("password");
		HtmlSubmitInput submit = assertingParty.getHtmlElementById("submit_button");
		username.setValueAttribute("user");
		password.setValueAttribute("password");
		HtmlPage relyingParty = submit.click();
		assertThat(relyingParty.asText())
				.contains("You're email address is testuser@spring.security.saml");
	}
}
